package com.siyoumi.util;


import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@NoArgsConstructor
@Accessors(chain = true)
public class XReturn
        extends LinkedHashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    public XReturn(@NonNull Integer errcode, String errmsg, HashMap<String, Object> data) {
        if (data == null) {
            data = new LinkedHashMap<>();
        }

        if (errmsg == null) {
            errmsg = "";
        }

        putAll(data);
        setData("errcode", errcode);
        setData("errmsg", errmsg);
        setData("api_date", XDate.toDateTimeString());
        setData("request_id", LogMdc.getRequestId());
    }

    static public XReturn getR(Integer errcode) {
        return new XReturn(errcode, "", null);
    }

    static public XReturn getR(Integer errcode, String errmsg) {
        return new XReturn(errcode, errmsg, null);
    }

    static public XReturn getR(Integer errcode, String errmsg, HashMap<String, Object> data) {
        return new XReturn(errcode, errmsg, data);
    }

    static public XReturn parse(String str) {
        XReturn r = XJson.parseObject(str, XReturn.class);
        if (!r.containsKey("errcode")) {
            r.setErrCode(0);
        }
        if (!r.containsKey("errmsg")) {
            r.setErrMsg("");
        }
        return r;
    }

    static public XReturn parse(Map<String, Object> data) {
        if (data == null) {
            return null;
        }
        XReturn r = XReturn.getR(0);
        r.putAll(data);
        return r;
    }

    public XReturn setData(@NonNull String k, Object v) {
        put(k, v);
        return this;
    }

    public <T> T getData(String k) {
        return getData(k, null);
    }

    public <T> T getData(@NonNull String k, T def) {
        Object v = get(k);
        if (v == null) {
            return def;
        }
        return (T) v;
    }

    /**
     * ok
     *
     * @return Boolean
     */
    public Boolean ok() {
        return getErrCode() == 0;
    }

    /**
     * error
     *
     * @return Boolean
     */
    public Boolean err() {
        return !ok();
    }


    public Integer getErrCode() {
        return getData("errcode", 0);
    }

    public void setErrCode(Integer errcode) {
        setData("errcode", errcode);
    }

    public String getErrMsg() {
        return getData("errmsg", "");
    }

    public void setErrMsg(String errmsg) {
        if (errmsg == null) {
            errmsg = "";
        }

        setErrMsg(new String[]{
                errmsg,
        });
    }

    public void setErrMsg(String... errmsg) {
        setData("errmsg", XStr.concat(errmsg));
    }

    public String toString() {
        return XJson.toJSONString(this);
    }
}
